//
//  XXRefresh.swift
//  GuoGuo
//
//  Created by 艾小新 on 16/8/11.
//  Copyright © 2016年 xiaoxin. All rights reserved.
//

import UIKit
/// 刷新控件的三种状态
///
/// - Normal:     默认
/// - Pulling:    松手就可以去刷新的状态
/// - Refreshing: 正在刷新的状态
enum XXFRESH : Int {
    case Normal = 0 , Pulling , Refreshing
}
// 当前刷新控件的高度
private let XXRefreshControlH: CGFloat = 50

class XXRefresh: UIControl {
    
    
    var scrollView : UIScrollView?
    
    // 代表当前控件的状态
    var refreshState: XXFRESH = .Normal {
        
        didSet {
            
            switch refreshState {
            case .Pulling:
//                print("进入松手就刷新状态")
                // 1. 文字改变
                info.text = "放开起飞"
                
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    // 2. 箭头调头
                    self.arrowImage.transform = CGAffineTransformMakeRotation(CGFloat(M_PI))
                })
                
            case .Normal:
//                print("默认状态")
                // 0. 箭头显示,菊花隐藏
                arrowImage.hidden = false
                activityIndicatorView.stopAnimating()
                // 1. 文字改变
                info.text = "下拉起飞"
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    // 2. 箭头调头
                    self.arrowImage.transform = CGAffineTransformIdentity
                })
                
                if oldValue == .Refreshing {
                    // 判断上一次状态是刷新中状态,那么进入到Normal状态就需要去减去InsetTop
                    UIView.animateWithDuration(0.25, animations: { () -> Void in
                        self.scrollView?.contentInset.top -= XXRefreshControlH
                    })
                }
            case .Refreshing:
//                print("刷新中状态")
                // 1. 隐藏箭头
                arrowImage.hidden = true
                // 2. 显示菊花转
                activityIndicatorView.startAnimating()
                // 3. 更改文字
                info.text = "正在起飞"
                // 4. 更改 contentInsetTop,让其停留在界面上
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.scrollView?.contentInset.top += XXRefreshControlH
                })
                
                // 刷新的时候要让控制器去 发送请求，就用这个方法
                sendActionsForControlEvents(UIControlEvents.ValueChanged)
            }
        }
        
        
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()   
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    // 设置页面
    private func setupUI() {
        
        backgroundColor = UIColor.whiteColor()
        // 设置其大小
        frame.size = CGSize(width: SCREENW, height: XXRefreshControlH)
        frame.origin.y = -XXRefreshControlH
        
        // 添加控件
        addSubview(activityIndicatorView)
        addSubview(arrowImage)
        addSubview(info)
        // 添加约束
        arrowImage.snp_makeConstraints { (make) in
            make.centerY.equalTo(self)
            make.centerX.equalTo(self).offset(-30)
            
        }
        activityIndicatorView.snp_makeConstraints { (make) in
            make.center.equalTo(arrowImage)
        }
        info.snp_makeConstraints { (make) in
            make.leading.equalTo(arrowImage.snp_trailing)
            make.centerY.equalTo(arrowImage)
        }
        
    }
    
    
    // 当添加到父控件的时候，可以从这个方法拿到父控件
    override func willMoveToSuperview(newSuperview: UIView?) {
        
        super.willRemoveSubview(newSuperview!)
        
        if let scrollView = newSuperview as? UIScrollView {
            
            // 转化成scrollView才能用content值
            // 开始监听 scroll增加刷新控件这个监听者
            scrollView.addObserver(self, forKeyPath: "contentOffset", options: [.Old,.New], context: nil)
            
            self.scrollView = scrollView
        }
        
        
    }
    
    // 当前控件观察的对象身上某个属性发生改变的时候会调用
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        
        // -114 怎么计算出来的??? -64-当前控件的高度
        let contentInsetTop = scrollView!.contentInset.top
        let contentOffsetY = scrollView!.contentOffset.y
        // 当前刷新控件在这种情况下完全显示出来的值
        let conditionValue = -contentInsetTop - XXRefreshControlH
        
        if scrollView!.dragging {
            
            
            // 如果当前的contentOffset.y小于或者等于conditionValue,那么就代表当前控件完全显示出来
            // 如果上面条件满足,并且当前状态是默认状态,那么就进入到 松手就刷新的状态(.Pulling)
            if contentOffsetY <= conditionValue && refreshState == .Normal {
                refreshState = .Pulling
//                print("松手就刷新")
            }else if refreshState == .Pulling && contentOffsetY > conditionValue{
                // 如果当前是松手就刷新状态,用户不松,把控件推回去.那么就设置当前状态为 .Normal
                // 在这儿要设置成 normal
                refreshState = .Normal
//                print("进入默认状态")
            }
        }else{
            // 如果用户松手并且如果当前状态是Pulling状态,就进入到 Refreshing状态
            if refreshState == .Pulling {
                refreshState = .Refreshing
//                print("进入刷新状态")
            }
            
        }

    }
    
    // 恢复最初
    func stopAnimating() {
        
        refreshState = .Normal
        
        
        
        
    }
    
    // 一定要删除观察者
    deinit {
        scrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
    // MARK: -懒加载
    // 1.菊花
    private lazy var activityIndicatorView :UIActivityIndicatorView = {
        
       let act = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
        
        return act
        
    }()
    // 2.箭头
    private lazy var arrowImage: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    
    // 3.文字
    private lazy var info: UILabel = {
        
       let lab = UILabel(title: "上拉刷新", color: UIColor.grayColor())
        lab.font = UIFont.systemFontOfSize(13)
        
       return lab
    }()
}
